package com.github.permissiondog.cancanpbackend.servlet;

import com.github.permissiondog.cancanpbackend.model.User;
import com.github.permissiondog.cancanpbackend.response.BaseResponse;
import com.github.permissiondog.cancanpbackend.util.JSON;

import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import javax.json.bind.JsonbException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.io.IOException;
import java.util.Set;

public class BaseServlet extends HttpServlet {
    private static final Validator VALIDATOR;

    static {
        try (ValidatorFactory vf = Validation.buildDefaultValidatorFactory()) {
            VALIDATOR = vf.getValidator();
        }
    }

    protected <T> T bind(HttpServletRequest req, HttpServletResponse res, Class<T> type) throws IOException {
        req.setCharacterEncoding("utf-8");
        if (!req.getContentType().startsWith("application/json")) {
            System.out.println(req.getContentType());
            json(res, BaseResponse.builder().ok(false).msg("不支持的 Content-Type").build());
            return null;
        }

        T obj;
        try {
            obj = JSON.JSONB.fromJson(req.getReader(), type);
        } catch (JsonbException e) {
            json(res, BaseResponse.builder().ok(false).msg("参数错误").build());
            return null;
        }

        Set<ConstraintViolation<T>> violation = VALIDATOR.validate(obj);
        if (!violation.isEmpty()) {
            String msg = violation.stream().findFirst().get().getMessage();
            json(res, BaseResponse.builder().ok(false).msg(msg).build());
            return null;
        }

        return obj;
    }

    protected void json(HttpServletResponse res, Object obj) throws IOException {
        res.setCharacterEncoding("utf-8");
        res.setContentType("application/json");
        JSON.JSONB.toJson(obj, res.getWriter());
    }

    protected User userLoggedIn(HttpServletRequest req) {
        return (User) req.getAttribute("user");
    }
}
